package org.jfonia.connect5.numerical;

import org.jfonia.connect5.basics.BasicValueNode;
import org.jfonia.connect5.basics.MutableValueNode;
import org.jfonia.connect5.basics.ValueNode;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import org.jfonia.connect5.relations.Relation;

/**
 * @author wijnand.schepens@hogent.be
 */
public class SumRelationFactory
{
	public static <T> Relation makeSumRelation(Class<?> cl, ValueNode<T> a, MutableValueNode<T> b, MutableValueNode<T> c)
	{
		if (cl == Integer.class)
			return new IntSumRelation((ValueNode<Integer>)a, (MutableValueNode<Integer>)b, (MutableValueNode<Integer>)c);
		else if (cl == Double.class)
			return new DoubleSumRelation((ValueNode<Double>)a, (MutableValueNode<Double>)b, (MutableValueNode<Double>)c);
		else if (cl == Long.class)
                        return new LongSumRelation((ValueNode<Long>)a, (MutableValueNode<Long>)b, (MutableValueNode<Long>)c);
                else
                        throw new RuntimeException("Not implemented");
	}


//	public static <T> Relation makeSumRelation(Node<T> a, MutableNode<T> b, MutableNode<T> c)
//	{
//		Class<?> cl = a.getType();
//		if (cl == Integer.class)
//			return new IntSumRelation((Node<Integer>)a, (MutableNode<Integer>)b, (MutableNode<Integer>)c);
//		else if (cl == Double.class)
//			return new DoubleSumRelation((Node<Double>)a, (MutableNode<Double>)b, (MutableNode<Double>)c);
//		else
//			throw new RuntimeException("Not implemented");
//	}

	public static <T> void test(T x)
	{
		System.out.println(x.getClass());
		System.out.println(Integer.class);
		System.out.println(x.getClass() == Integer.class);
	}

	public static <T> void test2(ValueNode<T> a)
	{
		System.out.println(a.getClass());
		Class<?> cl[] = a.getClass().getInterfaces();
		for (Class<?> c: cl)
			System.out.println(":" + c);
		System.out.println(a.getClass().getGenericSuperclass());
		Type[] types = a.getClass().getGenericInterfaces();
		for (Type t : types)
			System.out.println("->" + t);

		ParameterizedType type = (ParameterizedType) types[0];
		System.out.println(type.getActualTypeArguments()[0]);

		System.out.println( (Class<T>)type.getActualTypeArguments()[0] );

//		assertEquals(Map.class, type.getRawType());
//		assertEquals(String.class, type.getActualTypeArguments()[0]);
//		assertEquals(Integer.class, type.getActualTypeArguments()[1]);
	}
	

	public static void main(String[] args)
	{
		MutableValueNode<Integer> iNode = new BasicValueNode<Integer>(0);
		MutableValueNode<Double> dNode = new BasicValueNode<Double>(0.0);

		test(12);
		test(12.0);
		test(iNode);

		test2(iNode);

		Relation r;
		r = makeSumRelation(Integer.class, iNode, iNode, iNode);
		System.out.println(r);

//		r = makeSumRelation(iNode, iNode, iNode);
//		System.out.println(r);
//
//		r = makeSumRelation(Double.class, dNode, dNode, dNode);
//		System.out.println(r);
//
//		r = makeSumRelation(dNode, dNode, dNode);
//		System.out.println(r);
	}
}
